package org.cjlm.config;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.cjlm.exception.ConfigLoadException;

import java.io.InputStream;
import java.util.List;
import java.util.function.Function;

/**
 * 配置加载器 (优化版)
 * 特性：
 * 1. 统一资源加载逻辑
 * 2. 支持泛型类型安全
 * 3. 自定义异常体系
 * 4. 防御性编程
 */
public class ConfigLoader {
    private static final ObjectMapper MAPPER = new ObjectMapper();
    private static final String CONFIG_DIR = "config/";
    private static final String JSON_EXT = ".json";

    //---------------- 统一加载核心方法 -----------------
    private static <T> T loadConfig(String env, Function<InputStream, T> processor) {
        String path = CONFIG_DIR + env + JSON_EXT;

        try (InputStream is = Thread.currentThread()
                .getContextClassLoader()
                .getResourceAsStream(path)) {

            if (is == null) {
                throw new ConfigLoadException("配置文件未找到: " + path);
            }
            return processor.apply(is);

        } catch (ConfigLoadException e) {
            throw e; // 自定义异常直接抛出
        } catch (Exception e) {
            throw new ConfigLoadException("配置加载失败: " + path, e);
        }
    }

    //---------------- 类型化加载方法 -------------------
    public static AppConfig loadMainConfig(String env) {
        return loadConfig(env, is -> {
            try {
                return MAPPER.readValue(is,  AppConfig.class);
            } catch (Exception e) {
                throw new ConfigLoadException("主配置解析错误", e);
            }
        });
    }

    public static List<DbtypeConfig> loadDbtypeConfig(String env) {
        return loadConfig(env, is -> {
            try {
                return MAPPER.readValue(is,  new TypeReference<>() {});
            } catch (Exception e) {
                throw new ConfigLoadException("数据库类型配置解析错误", e);
            }
        });
    }

    public static List<InstanceConfig> loadInstanceConfig(String env) {
        return loadConfig(env, is -> {
            try {
                return MAPPER.readValue(is,  new TypeReference<>() {});
            } catch (Exception e) {
                throw new ConfigLoadException("实例配置解析错误", e);
            }
        });
    }
}